package com.example.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.exception.ServiceException;
import com.example.domain.dto.UserDTO;
import com.example.domain.entity.Role;
import com.example.domain.entity.User;
import com.example.domain.query.UserQuery;
import com.example.mapper.UserMapper;
import com.example.service.RoleService;
import com.example.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final PasswordEncoder passwordEncoder;
    private final UserMapper userMapper;
    private final RoleService roleService;

    @Override
    public User getUserByUsername(String username) {
        User user = userMapper.selectByUsername(username);
        if (user != null) {
            // 查询并设置用户角色信息
            List<Long> roleIds = userMapper.selectUserRoleIds(user.getId());
            user.setRoleIds(roleIds);
        }
        return user;
    }

    @Override
    public IPage<User> getUserPage(UserQuery query) {
        Page<User> page = new Page<>(query.getPageNum(), query.getPageSize());
        
        // 执行分页查询
        IPage<User> userPage = lambdaQuery()
                .and(StringUtils.hasText(query.getKeyword()), q -> q
                        .like(User::getUsername, query.getKeyword())
                        .or()
                        .like(User::getNickname, query.getKeyword())
                )
                .eq(StringUtils.hasText(query.getStatus()), User::getStatus, query.getStatus())
                .orderByDesc(User::getCreateTime)
                .page(page);
        
        // 查询用户角色信息
        userPage.getRecords().forEach(user -> {
            List<Long> roleIds = userMapper.selectUserRoleIds(user.getId());
            user.setRoleIds(roleIds);
            if (!CollectionUtils.isEmpty(roleIds)) {
                // 可以考虑批量查询优化
                List<Role> roles = roleService.listByIds(roleIds);
                user.setRoles(roles);
            }
        });
        
        return userPage;
    }

    @Override
    public User getUserById(Long id) {
        User user = getById(id);
        if (user != null) {
            user.setRoleIds(userMapper.selectUserRoleIds(id));
        }
        return user;
    }

    @Override
    public void addUser(UserDTO userDTO) {
        // 检查用户名是否已存在
        if (lambdaQuery().eq(User::getUsername, userDTO.getUsername()).exists()) {
            throw new com.example.common.exception.ServiceException("用户名已存在");
        }

        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        user.setPassword(passwordEncoder.encode(userDTO.getPassword()));

        // 保存用户
        save(user);

        // 保存用户角色关联
        if (!CollectionUtils.isEmpty(userDTO.getRoleIds())) {
            userMapper.insertUserRoles(user.getId(), userDTO.getRoleIds());
        }
    }

    @Override
    public void updateUser(UserDTO userDTO) {
        User user = getById(userDTO.getId());
        if (user == null) {
            throw new ServiceException("用户不存在");
        }

        // 如果修改了用户名，检查是否已存在
        if (!user.getUsername().equals(userDTO.getUsername())) {
            if (lambdaQuery().eq(User::getUsername, userDTO.getUsername()).exists()) {
                throw new ServiceException("用户名已存在");
            }
        }

        BeanUtils.copyProperties(userDTO, user);
        if (StringUtils.hasText(userDTO.getPassword())) {
            user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        }

        // 更新用户
        updateById(user);

        // 更新用户角色关联
        userMapper.deleteUserRoles(user.getId());
        if (!CollectionUtils.isEmpty(userDTO.getRoleIds())) {
            userMapper.insertUserRoles(user.getId(), userDTO.getRoleIds());
        }
    }

    @Override
    public void deleteUser(Long id) {
        // 删除用户角色关联
        userMapper.deleteUserRoles(id);
        // 删除用户
        removeById(id);
    }

    @Override
    public void batchDeleteUser(List<Long> ids) {
        // 删除用户角色关联
        ids.forEach(userMapper::deleteUserRoles);
        // 删除用户
        removeBatchByIds(ids);
    }

    @Override
    public List<Long> getUserRoleIds(Long userId) {
        return userMapper.selectUserRoleIds(userId);
    }

    @Override
    public void assignRoles(Long userId, List<Long> roleIds) {
        // 删除原有角色关联
        userMapper.deleteUserRoles(userId);
        // 添加新的角色关联
        if (!CollectionUtils.isEmpty(roleIds)) {
            userMapper.insertUserRoles(userId, roleIds);
        }
    }

    @Override
    public void updatePassword(String oldPassword, String newPassword) {
        // 获取当前用户
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        User user = getUserByUsername(username);

        // 验证旧密码
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new com.example.common.exception.ServiceException("原密码不正确");
        }

        // 更新密码
        user.setPassword(passwordEncoder.encode(newPassword));
        updateById(user);
    }
} 